package cn.zftt.quartz.dao.impl;

import cn.zftt.quartz.dao.JobLogDao;
import cn.zftt.quartz.model.JobLog;
import cn.zftt.quartz.model.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;

import java.sql.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author zhangfeng
 */
@Component
public class JobLogDaoImpl implements JobLogDao {

    private final JdbcTemplate jdbcTemplate;

    private static final String GET_LOGS = "SELECT * FROM JOB_LOGS WHERE JOB_NAME = ? AND JOB_GROUP = ?";

    private static final String START_INSERT = "INSERT INTO JOB_LOGS (JOB_NAME ,JOB_GROUP ,START_TIME) VALUES ( ? , ? , ? )";

    private static final String END_ERROR_INSERT = "UPDATE  JOB_LOGS  SET END_TIME  = ? ,JOB_EXCEPTION  = ? WHERE ID = ?";

    private static final String END_SUCCESS_INSERT = "UPDATE  JOB_LOGS  SET END_TIME  = ? ,MARK  = ?  WHERE ID = ?";

    @Override
    public Page<JobLog> getLogs(final JobLog jobLog) {
        if (jobLog != null && StringUtils.isNotEmpty(jobLog.getName()) && StringUtils.isNotEmpty(jobLog.getGroup())) {
            Integer total = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM (" + GET_LOGS + ")", Integer.class, jobLog.getName(), jobLog.getGroup());

            jobLog.setTotal(total);
            List<JobLog> logs = jdbcTemplate.query(GET_LOGS + " LIMIT " + (jobLog.getCur() - 1) * jobLog.getSize() + "," + jobLog.getSize(), new PreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps) throws SQLException {
                    ps.setString(1, jobLog.getName());
                    ps.setString(2, jobLog.getGroup());
                }
            }, new JobLogMapper());

            jobLog.setRows(logs);
            return jobLog;
        }
        Page t = new Page();
        t.setRows(Collections.emptyList());
        t.setTotal(0);
        return t;
    }


    private class JobLogMapper implements RowMapper<JobLog> {
        @Override
        public JobLog mapRow(ResultSet rs, int rowNum) throws SQLException {
            JobLog jobLog = new JobLog();
            jobLog.setId(rs.getLong("ID"));
            jobLog.setName(rs.getString("JOB_NAME"));
            jobLog.setGroup(rs.getString("JOB_GROUP"));
            if (rs.getLong("START_TIME") > 0)
                jobLog.setStartTime(new Date(rs.getLong("START_TIME")));
            if (rs.getLong("END_TIME") > 0)
                jobLog.setEndTime(new Date(rs.getLong("END_TIME")));
            jobLog.setMark(rs.getString("MARK"));
            jobLog.setJobException(rs.getString("JOB_EXCEPTION"));
            return jobLog;
        }
    }

    @Override
    public Long startInsert(JobLog jobLog) {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        if (jobLog != null && StringUtils.isNotEmpty(jobLog.getName()) && StringUtils.isNotEmpty(jobLog.getGroup()) && jobLog.getStartTime() != null)
            jdbcTemplate.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                    PreparedStatement preparedStatement = con.prepareStatement(START_INSERT, Statement.RETURN_GENERATED_KEYS);
                    preparedStatement.setString(1, jobLog.getName());
                    preparedStatement.setString(2, jobLog.getGroup());
                    preparedStatement.setLong(3, jobLog.getStartTime().getTime());
                    return preparedStatement;
                }
            }, keyHolder);
        return keyHolder.getKey().longValue();
    }

    @Override
    public Long endInsert(JobLog jobLog) {
        if (jobLog != null && jobLog.getId() != null && jobLog.getEndTime() != null)
            if (StringUtils.isNotEmpty(jobLog.getJobException()) && StringUtils.isEmpty(jobLog.getMark()))
                return (long) jdbcTemplate.update(END_ERROR_INSERT, new PreparedStatementSetter() {
                    @Override
                    public void setValues(PreparedStatement ps) throws SQLException {
                        ps.setLong(1, jobLog.getEndTime().getTime());
                        ps.setString(2, jobLog.getJobException());
                        ps.setLong(3, jobLog.getId());
                    }
                });
            else if (StringUtils.isEmpty(jobLog.getJobException()) && StringUtils.isNotEmpty(jobLog.getMark()))
                return (long) jdbcTemplate.update(END_SUCCESS_INSERT, new PreparedStatementSetter() {
                    @Override
                    public void setValues(PreparedStatement ps) throws SQLException {
                        ps.setLong(1, jobLog.getEndTime().getTime());
                        ps.setString(2, jobLog.getMark());
                        ps.setLong(3, jobLog.getId());
                    }
                });
        return 0L;
    }

    @Autowired
    public JobLogDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}
